package com.klun.concTrueWar.five;

import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.Semaphore;

/**
 * 使用 Semaphore 为容器设置边界
 * Semaphore （信号量） 用来控制同时访问某个特定资源的操作数量
 * 或者对容器施加边界
 * @param <T>
 */
public class BoundedHashSet<T> {
    private final Set<T> set;
    private final Semaphore sem;

    public BoundedHashSet(int bound){
        this.set = Collections.synchronizedSet(new HashSet<T>());
        // bound :允许同时运行的线程数目
        sem = new Semaphore(bound);
    }
    public boolean add(T o) throws InterruptedException {
        // ???? 获取获得  从信号量中获取一个机会
        sem.acquire();
        boolean wasAdded = false;
        try{
            wasAdded = set.add(o);
            return wasAdded;
        }
        finally {
            // 如果添加成功为什么不释放？？？
            if(!wasAdded){
                // ???  释放允许，将占有的信号量归还
                sem.release();
            }
        }
    }
    public boolean remove(Object o){
        boolean wasRemoved = set.remove(o);
        // 删除成功归还信号量
        if(wasRemoved){
            sem.release();
        }
        return wasRemoved;
    }
}
